home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xpaint-2.1.1
/
polyOp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
7KB
|
256 lines
/* +-------------------------------------------------------------------+ */
/* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
/* | | */
/* | Permission to use, copy, modify, and to distribute this software | */
/* | and its documentation for any purpose is hereby granted without | */
/* | fee, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. There is no | */
/* | representations about the suitability of this software for | */
/* | any purpose. this software is provided "as is" without express | */
/* | or implied warranty. | */
/* | | */
/* +-------------------------------------------------------------------+ */
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/cursorfont.h>
#include "xpaint.h"
#include "misc.h"
#include "Paint.h"
#define FILL 0x2
#define POLY 0x1
#define IsPoly(x) (x & POLY)
#define IsFill(x) (x & FILL)
#define MAXP 100
typedef struct {
int flag;
int startX, startY, endX, endY, button;
int drawn, first, tracking, go;
int npoints;
XPoint points[MAXP+1];
XPoint real[MAXP+1];
/*
** Borrowed from my info structure.
*/
GC fgc, lgc, gcx;
Pixmap pixmap;
Widget widget;
Boolean isFat;
} LocalInfo;
static void finish(Widget w, LocalInfo *l, Boolean flag)
{
if (!l->tracking)
return;
l->tracking = False;
if (l->drawn)
XDrawLines(XtDisplay(w), XtWindow(w), l->gcx,
l->points, l->npoints, CoordModeOrigin);
if (flag && l->drawn)
XDrawLine(XtDisplay(w), XtWindow(w), l->gcx,
l->points[l->npoints-1].x,
l->points[l->npoints-1].y,
l->endX, l->endY);
if (IsFill(l->flag)) {
if (!l->isFat)
XFillPolygon(XtDisplay(w), XtWindow(w), l->fgc,
l->real, l->npoints, Complex, CoordModeOrigin);
XFillPolygon(XtDisplay(w), l->pixmap, l->fgc,
l->real, l->npoints, Complex,CoordModeOrigin);
}
if (IsPoly(l->flag)) {
l->real[l->npoints].x = l->real[0].x;
l->real[l->npoints].y = l->real[0].y;
l->npoints++;
}
if (!l->isFat)
XDrawLines(XtDisplay(w), XtWindow(w), l->lgc,
l->real, l->npoints, CoordModeOrigin);
XDrawLines(XtDisplay(w), l->pixmap, l->lgc,
l->real, l->npoints, CoordModeOrigin);
PwUpdate(w, NULL, False);
}
static void press(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
{
if (!l->tracking && event->button == Button1) {
l->endX = l->startX = event->x;
l->endY = l->startY = event->y;
l->button = event->button;
l->npoints = 0;
l->points[l->npoints].x = event->x;
l->points[l->npoints].y = event->y;
l->real[l->npoints].x = info->x;
l->real[l->npoints].y = info->y;
l->npoints++;
l->drawn = False;
l->tracking = True;
l->first = True;
l->isFat = info->isFat;
l->fgc = info->second_gc;
l->lgc = info->first_gc;
} else if (event->button == Button2 && l->tracking) {
finish(w, l, True);
return;
}
if (l->first && info->surface == opPixmap) {
UndoStartPoint(w, info, info->x, info->y);
l->pixmap = info->drawable;
l->widget = w;
}
}
static void release(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
{
if (l->npoints == MAXP - 1)
return;
if (info->surface == opWindow) {
if (!l->first) {
l->endX = l->points[l->npoints].x = event->x;
l->endY = l->points[l->npoints].y = event->y;
l->startX = event->x;
l->startY = event->y;
}
return;
}
if (l->first) {
l->first = False;
return;
}
/*
** else on the pixmap.
*/
l->real[l->npoints].x = info->x;
l->real[l->npoints].y = info->y;
l->npoints++;
UndoGrow(w, info->x, info->y);
}
static void motion(Widget w, LocalInfo *l, XMotionEvent *event, OpInfo *info)
{
/*
** Haven't done the first button press
*/
if (!l->tracking || l->first)
return;
if (l->drawn)
XDrawLine(XtDisplay(w), info->drawable, l->gcx,
l->startX, l->startY, l->endX, l->endY);
l->endX = event->x;
l->endY = event->y;
if (l->drawn = (l->startX != l->endX && l->startY != l->endY))
XDrawLine(XtDisplay(w), info->drawable, l->gcx,
l->startX, l->startY, l->endX, l->endY);
}
/*
** Those public functions
*/
void *PolyAdd(Widget w)
{
LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
l->flag = POLY;
l->drawn = False;
l->first = True;
l->tracking = False;
l->gcx = GetGCX(w);
XtVaSetValues(w, XtNcompress, True, NULL);
OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
SetCrossHairCursor(w);
return l;
}
void PolyRemove(Widget w, LocalInfo *l)
{
OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
finish(w, l, True);
XtFree((XtPointer)l);
}
void *FPolyAdd(Widget w)
{
LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
l->flag = POLY|FILL;
l->drawn = False;
l->first = True;
l->tracking = False;
l->gcx = GetGCX(w);
XtVaSetValues(w, XtNcompress, True, NULL);
OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
SetCrossHairCursor(w);
return l;
}
void FPolyRemove(Widget w, LocalInfo *l)
{
OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
finish(w, l, True);
XtFree((XtPointer)l);
}
void *CLineAdd(Widget w)
{
LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
l->flag = 0;
l->drawn = False;
l->first = True;
l->tracking = False;
l->gcx = GetGCX(w);
XtVaSetValues(w, XtNcompress, True, NULL);
OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
SetCrossHairCursor(w);
return l;
}
void CLineRemove(Widget w, LocalInfo *l)
{
OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
finish(w, l, True);
XtFree((XtPointer)l);
}